package com.amtf.datafile;

import org.jdom.Attribute;
import org.jdom.Element;

/**
 * @author hansong
 * 
 */
public class DataColumnDefinition {
	private DataRecordDefinition recordDefinition = null;
	private String name = "";
	private boolean checkFormat = true;
	private boolean checkNGException = false;
	private boolean allowEmpty = true;
	private int minLength = 0;
	private int maxLength = -1;
	private VALUE_TYPE type = VALUE_TYPE.ANY;
	private PAD_TYPE padType = PAD_TYPE.NO_PAD;
	private String padValue = "";
	private boolean trimValue = false;
	private char quote = ' ';
	private boolean forceQuote = false;

	// private String description = "";

	public static enum PAD_TYPE {
		NO_PAD, RIGHT_PAD, LEFT_PAD;
	}

	public static enum VALUE_TYPE {
		ANY, ALPHABET, NUMERIC, ALPHABET_OR_NUMERIC;
	}

	// public DataColumnDefinition() {
	// }

	public DataColumnDefinition(DataRecordDefinition recordDefinition) {
		if (recordDefinition != null) {
			this.recordDefinition = recordDefinition;
			this.quote = this.recordDefinition.getSmartQuote();
		}
		// this.trimValue = trimValue;
	}

	public DataColumnDefinition(DataRecordDefinition definiton, String name, boolean check, boolean checkNGException, boolean allowEmpty, int minLength, int maxLength,
			VALUE_TYPE type, boolean trimValue, PAD_TYPE padType, String padValue) {
		this(definiton, name, check, checkNGException, allowEmpty, minLength, maxLength, type, trimValue, ' ', padType, padValue);
	}

	public DataColumnDefinition(DataRecordDefinition definiton, String name, boolean check, boolean checkNGException, boolean allowEmpty, int minLength, int maxLength,
			VALUE_TYPE type, boolean trimValue, char quote, PAD_TYPE padType, String padValue) {
		this.recordDefinition = definiton;
		this.name = name;
		this.checkFormat = check;
		this.checkNGException = checkNGException;
		this.allowEmpty = allowEmpty;
		this.maxLength = maxLength;
		this.minLength = minLength;
		this.type = type;
		this.padType = padType;
		this.trimValue = trimValue;
		this.quote = quote;

		if (padValue == null) {
			this.padValue = "";
		} else {
			this.padValue = padValue;
		}
	}

	public DataColumnDefinition(Element e, DataRecordDefinition definiton) {
		this.recordDefinition = definiton;

		try {
			this.name = e.getAttribute("name").getValue();
		} catch (Throwable e1) {
			this.name = "";
		}
		try {
			this.checkFormat = e.getAttribute("checkFormat").getBooleanValue();
		} catch (Throwable e1) {
			this.checkFormat = false;
		}
		try {
			this.allowEmpty = e.getAttribute("allowEmpty").getBooleanValue();
		} catch (Throwable e1) {
			this.allowEmpty = true;
		}
		try {
			this.maxLength = e.getAttribute("maxLength").getIntValue();
		} catch (Throwable e1) {
			this.maxLength = -1;
		}
		try {
			this.minLength = e.getAttribute("minLength").getIntValue();
		} catch (Throwable e1) {
			this.minLength = 0;
		}
		try {
			String valueTypeName = e.getAttribute("type").getValue();
			if ("n".equalsIgnoreCase(valueTypeName)) {
				this.type = VALUE_TYPE.NUMERIC;
			} else if ("a".equalsIgnoreCase(valueTypeName)) {
				this.type = VALUE_TYPE.ALPHABET;
			} else if ("an".equalsIgnoreCase(valueTypeName) || "na".equalsIgnoreCase(valueTypeName)) {
				this.type = VALUE_TYPE.ALPHABET_OR_NUMERIC;
			} else if ("any".equalsIgnoreCase(valueTypeName)) {
				this.type = VALUE_TYPE.ANY;
			} else {
				this.type = VALUE_TYPE.ANY;
			}

		} catch (Throwable e1) {
			this.type = VALUE_TYPE.ANY;
		}
		try {
			this.trimValue = e.getAttribute("trimValue").getBooleanValue();
		} catch (Throwable e1) {
			this.trimValue = false;
		}

		try {
			Attribute a_wipeSmartQuote = e.getAttribute("wipeSmartQuote");
			if (a_wipeSmartQuote != null && a_wipeSmartQuote.getBooleanValue() == false) {
				this.quote = ' ';
			} else {
				this.quote = definiton.getSmartQuote();
			}
		} catch (Throwable e1) {
			this.quote = definiton.getSmartQuote();
		}

		// try {
		// this.description = e.getAttribute("description").getValue();
		// } catch (Throwable e1) {
		// this.description = "";
		// }

		// ※※This code will be delete after※※Begin
		// if (e.getAttribute("wipeSmartQuote") == null) {
		// try {
		// Attribute elmQuote = e.getAttribute("valueInDoubleQuote");
		// if (elmQuote != null) {
		// boolean valueInDoubleQuote = elmQuote.getBooleanValue();
		// this.quote = valueInDoubleQuote ? '"' : ' ';
		// }
		// } catch (Throwable e2) {
		// this.quote = ' ';
		// }
		//
		// if (definiton.getSmartQuote() == ' ' && this.quote != ' ') {
		// definiton.setSmartQuote(this.quote);
		// }
		// }
		// ※※This code will be delete after※※End

		try {
			this.checkNGException = e.getAttribute("checkNGException").getBooleanValue();
		} catch (Throwable e1) {
			this.checkNGException = false;
		}

		try {
			Attribute atR = e.getAttribute("rightpad");
			Attribute atL = e.getAttribute("leftpad");
			if (atR != null) {
				this.padType = PAD_TYPE.RIGHT_PAD;
				this.padValue = atR.getValue();
			} else if (atL != null) {
				this.padType = PAD_TYPE.LEFT_PAD;
				this.padValue = atL.getValue();
			} else {
				this.padType = PAD_TYPE.NO_PAD;
				this.padValue = "";
			}
		} catch (Throwable e1) {
			this.padType = PAD_TYPE.NO_PAD;
			this.padValue = "";
		}
	}

	@Override
	protected DataColumnDefinition clone() {

		DataColumnDefinition newObj = new DataColumnDefinition(null);
		newObj.recordDefinition = this.recordDefinition;
		newObj.name = this.name;
		newObj.checkFormat = this.checkFormat;
		newObj.checkNGException = this.checkNGException;
		newObj.maxLength = this.maxLength;
		newObj.minLength = this.minLength;
		newObj.type = this.type;
		newObj.allowEmpty = this.allowEmpty;
		newObj.padType = this.padType;
		newObj.padValue = this.padValue;
		newObj.trimValue = this.trimValue;
		newObj.quote = this.quote;

		return newObj;
	}

	@Override
	public boolean equals(Object obj) {
		DataColumnDefinition f1 = (DataColumnDefinition) obj;

		return f1.name.equals(this.name) && f1.checkFormat == this.checkFormat && f1.checkNGException == this.checkNGException && f1.maxLength == this.maxLength
				&& f1.minLength == this.minLength && f1.type == this.type && f1.allowEmpty == this.allowEmpty && f1.padType == this.padType && f1.padValue.equals(this.padValue)
				&& f1.trimValue == this.trimValue && f1.quote == this.quote;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public boolean isCheckFormat() {
		return checkFormat;
	}

	public void setCheckFormat(boolean checkFormat) {
		this.checkFormat = checkFormat;
	}

	public boolean isCheckNGException() {
		return checkNGException;
	}

	public void setCheckNGException(boolean checkNGException) {
		this.checkNGException = checkNGException;
	}

	public boolean isAllowEmpty() {
		return allowEmpty;
	}

	public void setAllowEmpty(boolean allowEmpty) {
		this.allowEmpty = allowEmpty;
	}

	public int getMinLength() {
		return minLength;
	}

	public void setMinLength(int minLength) {
		this.minLength = minLength;
	}

	public int getMaxLength() {
		return maxLength;
	}

	public void setMaxLength(int maxLength) {
		this.maxLength = maxLength;
	}

	public VALUE_TYPE getType() {
		return type;
	}

	public void setType(VALUE_TYPE type) {
		this.type = type;
	}

	public PAD_TYPE getPadType() {
		return padType;
	}

	public void setPadType(PAD_TYPE padType) {
		this.padType = padType;
	}

	public String getPadValue() {
		return padValue;
	}

	public void setPadValue(String padValue) {
		this.padValue = padValue;
	}

	public boolean isTrimValue() {
		return trimValue;
	}

	public void setTrimValue(boolean trimValue) {
		this.trimValue = trimValue;
	}

	public DataRecordDefinition getDataRecordDefinition() {
		return recordDefinition;
	}

	public void setDataRecordDefinition(DataRecordDefinition recordDefinition) {
		this.recordDefinition = recordDefinition;
	}

	public boolean isForceQuote() {
		return forceQuote;
	}

	public void setForceQuote(boolean forceQuote) {
		this.forceQuote = forceQuote;
	}

	public char getQuote() {
		return quote;
	}

	public void setQuote(char quote) {
		this.quote = quote;
	}
}
